package com.up4years.dataapi.dao.base;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.up4years.dataapi.entity.base.Page;

/**
 * 分页查询专用
 * 
 * @author xuxingan
 * 
 */
@Repository
public class PageDao extends SqlSessionDaoSupport {

	@Resource
	@Override
	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		super.setSqlSessionFactory(sqlSessionFactory);
	}
	/**
	 * 分页
	 * @param <T>
	 */
	@Transactional(readOnly = true)
	public <T> Page<T> pageQuery(Page<T> page, String statementName,Object parameters){
 		this.selectPage(page,statementName , parameters);
 		return page;
	}
	/**
	 * 分页
	 * 
	 * @param page
	 * @param statementName
	 *            查询集合名称
	 * @param countStatementName
	 *            统计名称
	 * @param parameter
	 * @return
	 */
	private <T> Page<T> selectPage(Page<T> page, String listStatementName,
			String countStatementName, Object parameter) {
		//查出总条数
		Number totalItems = (Number) getSqlSession().selectOne( countStatementName, parameter);
		if (totalItems != null && totalItems.longValue() > 0) {
			int totalCount = totalItems.intValue();
			page.setTotalItems(totalCount);
			//处理参数
			Map<String,Object> params = toParameterMap(parameter, page);
			//查出全部
			List<T> list = getSqlSession().selectList(listStatementName,params);
			page.setResult(list);
		}
		return page;
	}
	/**
	 * 分页
	 * @param page
	 * @param statementName
	 * @param parameter
	 * @return
	 */
	private <T> Page<T> selectPage(Page<T> page, String statementName, Object parameter) {
		//使用该语句查出总条数
		String countStatementName = statementName + "Count";
		return selectPage(page, statementName, countStatementName, parameter);
	}
	
	private static Map<String, Object> toParameterMap(Object parameter,
			@SuppressWarnings("rawtypes") Page p) {
		Map<String, Object> map = toParameterMap(parameter);
		map.put("startRow", p.getStartRow());
		map.put("endRow", p.getEndRow());
		map.put("offset", p.getOffset());
		map.put("limit", p.getPageSize());
		return map;
	}

	@SuppressWarnings("unchecked")
	private static Map<String, Object> toParameterMap(Object parameter) {
		if (parameter instanceof Map) {
			return (Map<String, Object>) parameter;
		} else {
			try {
				return PropertyUtils.describe(parameter);
			} catch (Exception e) {
				org.springframework.util.ReflectionUtils
						.handleReflectionException(e);
				return null;
			}
		}
	}

}
